#include <stdio.h>
#include <unistd.h>

#include "arm_state.h"
#include "debug.h"
#include "globals.h"
#include "keypad_state.h"
#include "lcd_state.h"
#include "memory.h"
#include "state_loop.h"

int run_state_loop(void)
{
    int lCurrentState = STATE_NULL;
    int loop = LOOP_FOREVER;
    int retval = 0;
    
    /* State loop */
    while (loop == LOOP_FOREVER)
    {
        switch (lCurrentState)
        {
            /* House keeping */
            case STATE_NULL:
            {
                /* For now, just check keypad for IO */
                lCurrentState = STATE_KEYPAD_CHECK;
                
                usleep(100);    /* 100us sleep to prevent cpu thrashing */
            }
            break;
            
            /* Check for user input on the keypad */
            case STATE_KEYPAD_CHECK:
            {
                lCurrentState = keypad_check_state();
            }
            break;
            
            /* Handle any arm movements for this iteration */
            case STATE_ARM_MOVEMENT:
            {
                lCurrentState = arm_state();
            }
            break;
            
            /* Print any data to the LCD screen */
            case STATE_LCD_OUT:
            {
                lCurrentState = lcd_state();
            }
            break;
            
            /* Handle user IO from keypad */
            case STATE_HANDLE_KEYPAD_IO:
            {
                lCurrentState = keypad_handle_io_state();
            }
            break;
            
            /* Exit the program */
            case STATE_EXIT:
            {
                loop = LOOP_STOP;
            }
            break;
            
            /* Halt the program in this state - infinite loop */
            case STATE_HOLDING_STATE:
            {
                /* TODO Consider using a hold flag that will allow for IO check
                        to try and get out of whatever put us in this state. 
                        e.g. Poll for user io on keypad. If none, return to 
                        holding state. If IO, change state to io handler. If 
                        a suitable input value to get out of this state, the 
                        program will continue to run as before, otherwise this
                        state will be re-entered. */
            }
            break;
            
            /* Catch unknown values - this should never happen */
            default:
            {
                printf("Unknown state: %d\r\n", lCurrentState);
                loop = LOOP_STOP;
                retval = (-1);
            }
            break;
        }
    }
    
    return retval;
}
